---@class TBS.ActorMgr
local ActorMgr = TBS.CreateSingleton("ActorMgr")
local this = ActorMgr
function ActorMgr.OnCreate()
    ---@type TBS.Player[]
    this.actorList = {}     --英雄列表
    this.playerStaticId = 0
    ---@type TBS.Player[][]
    this.groupList = {}     --英雄组，英雄普攻释放列表
    ---@type TBS.Player[]
    this.leaderList = {}    --领导，组技能释放者
    ---@type TBS.Player
    this.bossActor = nil
    TBS.Battle.RegisterUpdateCallback(this.Update)
    this.leaderSkillList = {}
end
function ActorMgr.OnDestroy()
    if this.actorList then
        for k,v in pairs(this.actorList) do
            v:BaseDestroy()
        end
    end
    this.actorList = nil
    this.groupList = nil
    this.leaderList = nil
    this.bossActor = nil
    this.leaderSkillList = nil
end
function ActorMgr.GetUniqueId()
    this.playerStaticId = this.playerStaticId + 1
    return this.playerStaticId
end
---@return TBS.Player
function ActorMgr.CreatePlayer(id,modelId,actorType,name)
    local player = TBS.Player.New(actorType)
    player:BaseCreate()
    player.id = tostring(id)
    player.name = name
    player:SetModel(modelId)
    player:SetHp(1000)
    player:SetHpMax(1000)
    player:SetPos(0,0)
    return player
end

---@param actor TBS.Player
function ActorMgr.AddActor(actor)
    if actor == nil then return end
    local a = this.GetActor(actor:GetId())
    if a ~= nil then
       -- logError("尝试添加一个重复的actor:"..actor:GetId())
        return
    end
    this.actorList[actor:GetId()] = actor
end
---@param actor TBS.Player
function ActorMgr.AddGroup(groupId,index,actor)
    local _list = this.groupList[groupId]
    if not _list then
        _list = {}
        this.groupList[groupId] = _list
    end
    _list[index] = actor
    this.AddActor(actor)
end
---@param actor TBS.Player
function ActorMgr.AddLeader(groupId,actor)
    this.leaderList[groupId] = actor
    this.AddActor(actor)
end
---@param actor TBS.Player
function ActorMgr.AddBoss(actor)
    this.bossActor = actor
    this.AddActor(actor)
end
---@param actor TBS.Player
function ActorMgr.DestroyActor(actor)
    if not actor then return end
    this.actorList[actor:GetId()] = nil
    FireEvent(TBS.Config.Event.ActorDestroy,actor)
    actor:BaseDestroy()
end

---@return TBS.Player
function ActorMgr.GetActor(playerId)
    if not this.actorList then return nil end
    local actor = this.actorList[playerId]
    return actor
end
function ActorMgr.GetActorList()
    return this.actorList
end
function ActorMgr.GetMaxGroupCount()
    return table.getn(this.groupList)
end
---@return TBS.Player
function ActorMgr.GetBoss()
    return this.bossActor
end
---@return TBS.Player[]
function ActorMgr.GetGroupActors(groupId)
    return this.groupList[groupId]
end
function ActorMgr.GetAllGroups()
    return this.groupList
end
---@return TBS.Player
function ActorMgr.GetGroupLeader(groupId)
    return this.leaderList[groupId]
end
---@return TBS.Player[]
function ActorMgr.GetLeaderList()
    return this.leaderList
end
function ActorMgr.LeaderTurnStartAll()
    for k,v in pairs(this.leaderSkillList) do
        this.LeaderTurnStart(k)
    end
end
function ActorMgr.LeaderTurnStart(groupId)
    local skill = this.GetLeaderSkill(groupId)
    if skill.cd == 0 then
        skill.cd = skill.maxCd
    else
        skill.cd = skill.cd - 1
    end
end
function ActorMgr.InitLeaderSkill()
    local skillTB = {}
    local cfg = dataTable.getDataTable("t_collocationskill")
    for k,v in pairs(cfg) do
        if v.f_Collocation ~= "" then
            for index,h in pairs(v.f_Collocation) do
                local heroList = skillTB[v.f_Id]
                if not heroList then
                    heroList = {}
                    skillTB[v.f_Id] = heroList
                end
                heroList[h[1]] = h[2]
            end
        end
    end

    for i = 1,4 do
        local actors = this.GetGroupActors(i)
        if actors then
            local tb = TablePool.Get()
            for k,v in pairs(actors) do
                table.insert(tb,v:GetModelId())
            end
            local skillId = TBS.Battle.GetSpecialSkill(tb)
            this.SetLeaderSkill(i,skillId)
            TablePool.ReleaseDeeper(tb,false)
        else
            this.SetLeaderSkill(i,0)
        end
    end

end
function ActorMgr.SetLeaderSkill(groupId,skillId)
    local skill = this.leaderSkillList[groupId]
    if skillId == 0 then
        this.leaderSkillList[groupId] = nil
        return
    end
    local cfg = dataTable.getDataTableByStringId("t_collocationskill",skillId)
    if not cfg then return end
    skill = {skillId = skillId,cd = cfg.f_InitialCD,maxCd = cfg.f_SkillCD}
    this.leaderSkillList[groupId] = skill
end
---@return {skillId:number,cd:number,maxCd:number}
function ActorMgr.GetLeaderSkill(groupId)
    return this.leaderSkillList[groupId]
end
function ActorMgr.Update(dt)
    for k,v in pairs(this.actorList) do
        v:Update(dt)
    end
end